package com.hxz.graduationdesign.util;

import com.hxz.graduationdesign.pojo.entity.Danmu;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class BilibiliDanmuCrawler {

    private static final String VIDEO_INFO_API = "https://api.bilibili.com/x/web-interface/view?bvid=";
    private static final String DANMU_API = "https://api.bilibili.com/x/v1/dm/list.so?oid=";

    public static List<Danmu> getDanmu(String bvid) {
//        String bvid = "BV1R94y1672s";
        try {
            List<String> danmuList = getDanmuByBvid(bvid);
            List<Danmu> danmus = new ArrayList<>();
//            System.out.println("共获取到 " + danmuList.size() + " 条弹幕");
            for (String danmuString : danmuList) {
                Danmu danmu = new Danmu();
                danmu.setBv(bvid);
                danmu.setDanmu(danmuString);
//                System.out.println(danmu);
                danmus.add(danmu);
            }
            return danmus;
        } catch (Exception e) {
            throw new RuntimeException("弹幕获取失败，视频不存在或视频已下架");
        }
    }

    public static List<String> getDanmuByBvid(String bvid) throws Exception {
        String cid = getCidByBvid(bvid);
        if (cid == null || cid.isEmpty()) {
            throw new Exception("无法获取视频CID");
        }
        return getDanmuByCid(cid);
    }

    private static String getCidByBvid(String bvid) throws IOException {
        String url = VIDEO_INFO_API + bvid;
        String response = sendGetRequest(url);

        JSONObject json = new JSONObject(response);
        if (json.getInt("code") != 0) {
            return null;
        }

        JSONObject data = json.getJSONObject("data");
        Object cidObj = data.get("cid");

        if (cidObj instanceof Integer) {
            return String.valueOf(cidObj);
        } else if (cidObj instanceof Long) {
            return String.valueOf(cidObj);
        } else if (cidObj instanceof String) {
            return (String) cidObj;
        } else {
            throw new IOException("无法识别的cid类型: " + cidObj.getClass().getName());
        }
    }

    private static List<String> getDanmuByCid(String cid) throws Exception {
        List<String> danmuList = new ArrayList<>();
        String url = DANMU_API + cid;
        String response = sendGetRequest(url);

        Document document = DocumentHelper.parseText(response);
        Element root = document.getRootElement();

        List<Element> dElements = root.elements("d");
        for (Element d : dElements) {
            danmuList.add(d.getText());
        }

        return danmuList;
    }

    private static String sendGetRequest(String url) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);

        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
        httpGet.setHeader("Referer", "https://www.bilibili.com/");

        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, "UTF-8");
        }
    }
}